<template>
  <el-button icon="add" type="primary" style="margin-bottom: 5px" round @click="addNewButton">添加自定义按钮</el-button>

  <el-table height="100%" border stripe
            :data="editingMenu.menuButtons">
    <el-table-column show-overflow-tooltip prop="buttonName" label="按钮名称">
      <template #default="{row}">
        <el-input v-model="row.buttonName" placeholder="请输入按钮名称"/>
      </template>
    </el-table-column>

    <el-table-column show-overflow-tooltip prop="buttonActionType" label="按钮类型">
      <template #default="{row}">
        <el-select v-model="row.buttonActionType" placeholder="请选择按钮类型"
                   @change="() => buttonActionTypeChange(row)">
          <el-option v-for="opt in buttonActionTypeOption" :label="opt.title" :value="opt.value" :key="opt.value"/>
        </el-select>
      </template>
    </el-table-column>

    <el-table-column show-overflow-tooltip prop="processDefinitionId" label="绑定流程">
      <template #default="{row}">
        <el-select v-model="row.processDefinitionId" v-show="showProcessDefinition(row)"
                   placeholder="请选择流程" @change="() => processDefinitionChange(row)">
          <el-option v-for="opt in formDefinition.flows" :label="opt.name" :value="opt.id" :key="opt.id"/>
        </el-select>
      </template>
    </el-table-column>

    <el-table-column show-overflow-tooltip prop="pcViewId" label="pc视图">
      <template #default="{row}">
        <span>
          <el-select v-model="row.pcViewId" placeholder="请选择视图"
                     v-if="isShowViewSelector(row)" @change="() => pcViewChange(row)">
          <el-option v-for="opt in formDefinition.views" :label="opt.viewName" :value="opt.id" :key="opt.id"/>
        </el-select>
        </span>
      </template>
    </el-table-column>
    <el-table-column show-overflow-tooltip prop="pcViewActionId" label="pc视图权限">
      <template #default="{row}">
        <el-select v-model="row.pcViewActionId" v-if="isShowViewSelector(row) && isNotEmpty(pcActionOptionsMap[row.id])"
                   placeholder="请选择视图权限">
          <el-option v-for="opt in pcActionOptionsMap[row.id]" :value="opt.id" :label="opt.actionName" :key="opt.id"/>
        </el-select>
      </template>
    </el-table-column>
    <el-table-column show-overflow-tooltip prop="mobileViewId" label="移动端视图">
      <template #default="{row}">
        <el-select v-model="row.mobileViewId" v-if="isShowViewSelector(row)"
                   placeholder="请选择视图" @change="() => mobileViewChange(row)">
          <el-option v-for="opt in formDefinition.views" :label="opt.viewName" :value="opt.id" :key="opt.id"/>
        </el-select>
      </template>
    </el-table-column>
    <el-table-column show-overflow-tooltip prop="mobileViewActionId" label="移动端视图权限">
      <template #default="{row}">
        <el-select v-model="row.mobileViewActionId" v-if="isShowViewSelector(row) && isNotEmpty(mobileActionOptionsMap[row.id])"
                   placeholder="请选择视图权限">
          <el-option v-for="opt in mobileActionOptionsMap[row.id]" :value="opt.id" :label="opt.actionName"
                     :key="opt.id"/>
        </el-select>
      </template>
    </el-table-column>
    <el-table-column show-overflow-tooltip prop="forRow" width="70" label="行显示">
      <template #default="{row}">
        <span v-show="row.buttonActionType !== 'createForm'">
          <el-checkbox v-model="row.forRow" true-label="true" false-label="false"/>
        </span>
      </template>
    </el-table-column>
    <el-table-column show-overflow-tooltip prop="forRow" label="设置组件">
      <template #default="{row}">
        <el-input v-model="row.buttonComponent"/>
      </template>
    </el-table-column>
    <el-table-column prop="forRow" width="200" label="功能设置">
      <template #default="{row}">
        <el-button :icon="hasRelation(row) ? 'ok' : undefined"
                   :type="hasRelation(row) ? 'primary' : 'default'"
                   v-show="row.buttonActionType === 'relateForm'"
                   @click="() => configButtonAction(row)"
                   round plain>字段映射
        </el-button>
        <el-button icon="remove" type="warning" @click="() => removeButton(row)" round/>
      </template>
    </el-table-column>
  </el-table>
  <RelationConfiguration :formDefinition="formDefinition"
                         :edittingButton="edittingButton"
                         ref="refRelationConfiguration"/>
</template>
<script setup>
import {DefaultFormDefinition, DefaultMenuButton, DefaultMenuDefinition} from '@/components/form/DefaultFormDefinition';
import {nextTick, reactive, shallowRef, watchEffect} from 'vue';
import {isEmpty, isNotEmpty} from '@/utils/CommonUtils';
import RelationConfiguration from '@/components/form/FormMenuButtonConfiguration/RelationConfiguration.vue';
import {ElMessage, ElMessageBox} from 'element-plus';

defineOptions({
  name: 'FormMenuButtonConfiguration'
});
const props = defineProps({
  editingMenu: JSON.parse(JSON.stringify(DefaultMenuDefinition)),
  formDefinition: JSON.parse(JSON.stringify(DefaultFormDefinition))
});
const edittingButton = shallowRef();
const refRelationConfiguration = shallowRef();
const pcActionOptionsMap = reactive({});
const mobileActionOptionsMap = reactive({});
const buttonActionTypeOption = shallowRef([
  {title: '新建表单', value: 'createForm'},
  {title: '显示详情', value: 'detail'},
  {title: '编辑表单', value: 'edit'},
  {title: '新建其他单据', value: 'relateForm'},
]);

function buttonActionTypeChange(row) {
  row.pcViewId = undefined;
  row.mobileViewId = undefined;
  row.pcViewActionId = undefined;
  row.mobileViewActionId = undefined;

  resolveDefaultComponent(row);
  if (row.buttonActionType === 'createForm') {
    row.forRow = false;
  }
}

function resolveDefaultComponent(row) {
  if (isEmpty(row.component) || isDefaultButtonComponent(row.component)) {
    //默认的组件, 接着设置默认的组件
    setDefaultComponent(row);
  }
}

function setDefaultComponent(row) {
  if (row.buttonActionType === 'createForm') {
    row.buttonComponent = 'platwork/FormListButton/CreateFormButton';
  }

  if (row.buttonActionType === 'edit') {
    row.buttonComponent = 'platwork/FormListButton/EditFormButton';
  }

  if (row.buttonActionType === 'detail') {
    row.buttonComponent = 'platwork/FormListButton/DetailFormButton';
  }

  if (row.buttonActionType === 'relateForm') {
    row.buttonComponent = 'platwork/FormListButton/RelationFormButton';
  }
}

function isDefaultButtonComponent(component) {
  let list = ['platwork/FormListButton/CreateFormButton',
    'platwork/FormListButton/EditFormButton',
    'platwork/FormListButton/DetailFormButton'];
  return list.findIndex(c => c === component) !== -1;
}

function addNewButton() {
  let button = JSON.parse(JSON.stringify(DefaultMenuButton));
  setDefaultComponent(button);
  props.editingMenu.menuButtons.push(button);
}

function processDefinitionChange(row) {
  row.pcViewId = undefined;
  row.mobileViewId = undefined;
  row.mobileViewActionId = undefined;
  row.pcViewActionId = undefined;
}

function showProcessDefinition(row) {
  if (props.formDefinition.processForm &&
      row.buttonActionType === 'createForm') {
    return true;
  }
  return false;
}

function isShowViewSelector(row) {
  if (showProcessDefinition(row)) return false;
  if (row.buttonActionType === 'createForm'
      || row.buttonActionType === 'detail'
      || row.buttonActionType === 'edit') {
    return true;
  }
  return false;
}

watchEffect(() => {
  resolveActionOptsMap();
});

function resolveActionOptsMap() {
  let list = props.editingMenu.menuButtons;
  if (isEmpty(list)) return;
  list.forEach(button => {
    resolveButtonActions(button);
  });
}

function resolveButtonActions(button) {
  if (isEmpty(button)) return;
  if (button.buttonActionType === 'detail') {
    pcActionOptionsMap[button.id] = undefined;
    mobileActionOptionsMap[button.id] = undefined;

    button.pcViewActionId = undefined;
    button.mobileViewActionId = undefined;
    return;
  }
  let pcViewId = button.pcViewId;
  pcActionOptionsMap[button.id] = props.formDefinition.viewActions.filter(v => v.viewId === pcViewId);

  let mobileViewId = button.mobileViewId;
  mobileActionOptionsMap[button.id] = props.formDefinition.viewActions.filter(v => v.viewId === mobileViewId);
}

function mobileViewChange(button) {
  button.mobileViewActionId = undefined;

  resolveButtonActions(button);
}

function pcViewChange(button) {
  button.pcViewActionId = undefined;
  if (button.buttonActionType === 'relateForm' || button.buttonActionType === 'detail') {
    return;
  }
  resolveButtonActions(button);
}

function hasRelation(button) {
  return isNotEmpty(button) && isNotEmpty(button.relations);
}

function configButtonAction(button) {
  edittingButton.value = button;
  nextTick(() => {
    refRelationConfiguration.value.open();
  });
}

function removeButton(row) {
  ElMessageBox.confirm('删除后不可恢复, 确定删除吗?', '确定删除?', {
    draggable: true,
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    let index = props.editingMenu.menuButtons.findIndex(b => b.id === row.id);
    if (index !== -1) {
      props.editingMenu.menuButtons.splice(index, 1);
    }
  }).catch(() => {
  });
}

function checkCreateFormButton(button) {
  if (showProcessDefinition(button)) {//流程表单
    if (isEmpty(button.processDefinitionId)) {
      return false;
    }
  } else { //非流程表单
    if (isEmpty(button.pcViewId) ||
        isEmpty(button.pcViewActionId) ||
        isEmpty(button.mobileViewId) ||
        isEmpty(button.mobileViewActionId)) {
      return false;
    }
  }
  return true;
}

function checkDetailButton(button) {
  if (isEmpty(button.pcViewId) || isEmpty(button.mobileViewId)) {
    return false;
  }
  return true;
}

function checkEditButton(button) {
  if (isEmpty(button.pcViewId) ||
      isEmpty(button.pcViewActionId) ||
      isEmpty(button.mobileViewId) ||
      isEmpty(button.mobileViewActionId)) {
    return false;
  }
  return true;
}

function checkRelateFormButton(button) {
  if (isEmpty(button.relations)) {
    ElMessage({
      showClose: true,
      message: '请配置字段映射',
      type: 'warning',
    });
    return false;
  }
  return true;
}

function checkButton(button) {
  if (isEmpty(button.buttonName)
      || isEmpty(button.buttonComponent
          || isEmpty(button.buttonActionType))) {

    return false;
  }

  if (button.buttonActionType === 'createForm') {
    return checkCreateFormButton(button);
  }

  if (button.buttonActionType === 'detail') {
    return checkDetailButton(button);
  }

  if (button.buttonActionType === 'edit') {
    return checkEditButton(button);
  }

  if (button.buttonActionType === 'relateForm') {
    return checkRelateFormButton(button);
  }
}

function checkButtons() {
  return new Promise((success, err) => {
    let buttons = props.editingMenu.menuButtons;
    if (isEmpty(buttons)) success();
    for (let i = 0; i < buttons.length; i++) {
      if (!checkButton(buttons[i])) {
        ElMessage({
          showClose: true,
          message: '请将自定义按钮的必填项填写完整',
          type: 'warning',
        });
        return;
      }
    }

    success();
  });
}

defineExpose({
  checkButtons,
});
</script>
